home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / utils / nap / NAP_Mods.b < prev    next >
Encoding:
Text File  |  1996-08-28  |  20.6 KB  |  713 lines

  1.  
  2. {********************************************************************
  3. ** NAP_Mods : Sub modules needed by NAP.                           **
  4. **                                                                 **
  5. ** For information about the copyright read the corresponding sec- **
  6. ** tion in NAP.doc, since these modules are part of NAP.           **
  7. *********************************************************************
  8. ** Copy - copies a string into an allocated memoryblock            **
  9. **                                                                 **
  10. **   Syntax : memorypos = Copy(text)                               **
  11. **                                                                 **
  12. **     memorypos      : (address) a pointer to the memory block    **
  13. **                      the string has been copied to              **
  14. **     text           : (string) the string to be stored           **
  15. **                                                                 **
  16. ** Comment : There'll be no checking whether the memory block has  **
  17. **           been allocated successfully !!!                       **
  18. *********************************************************************
  19. ** Search2 - replace of INSTR (faster than INSTR)                  **
  20. **                                                                 **
  21. **   Syntax : found_position = Search2(start,text,snippet)         **
  22. **                                                                 **
  23. **     found_position : (shortint) Contains the number of the byte **
  24. **                      where the strings match/0 if nothing found **
  25. **     start          : (shortint) where to start comparing        **
  26. **     text           : (string) String to be searched             **
  27. **     snippet        : (string) String to look for in <text>      **
  28. **                                                                 **
  29. **  Comment : <start> is NOT optional                              **
  30. *********************************************************************
  31. ** Legal - checks whether a specified byte of a string is within a **
  32. **         comment ala ACE or within a string                      **
  33. **                                                                 **
  34. **   Syntax : Result = Legal(text,position)                        **
  35. **                                                                 **
  36. **     Result         : (shortint) Is 1 if neither within a string **
  37. **                      nor a comment. Otherwise 0                 **
  38. **     Text           : (string)                                   **
  39. **     Position       : (shortint) byte to check                   **
  40. *********************************************************************
  41. ** UpperCase$ - makes a string uppercase (faster than UCASE$)      **
  42. **                                                                 **
  43. **   Syntax : upcase = UpperCase$(lowercase)                       **
  44. **                                                                 **
  45. **     upcase         : (string) same as <lowercase> but uppercase **
  46. **     lowercase      : (string) string to be upcased              **
  47. *********************************************************************
  48. ** AlreadyInList - checks whether a specified string is already    **
  49. **                 saved in a certain list                         **
  50. **                                                                 **
  51. **   Syntax : Result = AlreadyInList(begin_of_list,what)           **
  52. **                                                                 **
  53. **     result         : (address) Pointer to entry, 0 if none      **
  54. **     begin_of_list  : (address) pointer to the first entry of a  **
  55. **                      "LinkedList"                               **
  56. **     what           : (string) String to be looked for           **
  57. **                                                                 **
  58. ** Comment : This routine is since NAP 2.00b2 obsolete. Before it  **
  59. **           I used my own linked structures but since then NAP is **
  60. **           using the exec structures which are also supported by **
  61. **           some exec routines, namely FindName& which does re-   **
  62. **           place AlreadyInList since version 2.00b2              **
  63. *********************************************************************
  64. ** CutOff - cuts off the right part of a string after a specified  **
  65. **          position, if this position is neither within a comment **
  66. **          nor a string                                           **
  67. **                                                                 **
  68. **   Syntax : cutted = CutOff(text,position)                       **
  69. **                                                                 **
  70. **     cutted         : (string) cutted string                     **
  71. **     text           : (string) string to be cutted               **
  72. **     position       : (shortint) position from which to cut      **
  73. **                                                                 **
  74. ** Comment : To recognize whether <position> is within a string or **
  75. **           a comment the LEGAL routine (see above) is used.      **
  76. *********************************************************************
  77. ** Get_name_of_object : Gets the next text within a string that is **
  78. **                      embetted in spaces                         **
  79. **                                                                 **
  80. **   Syntax : object = Get_name_of_object (startpos,text)          **
  81. **                                                                 **
  82. **     object         : (string) name of object                    **
  83. **     startpos       : (shortint) where to start looking for      **
  84. **     text           : (string) string to be gone through         **
  85. *********************************************************************
  86. ** Get_name_of_object_alt : Same as "Get_name_of_object" but looks **
  87. **                          for a string that is not within a-Z,   **
  88. **                          0-9, "_" and "."                       **
  89. *********************************************************************
  90. ** ReplaceC : Replaces a certain text within a specified string    **
  91. **                                                                 **
  92. **   Syntax : replaced = ReplaceC(text,toReplace,replace)          **
  93. **                                                                 **
  94. **     replaced       : (string) returned string where the text    **
  95. **                      has been replaced                          **
  96. **     text           : (string) the string where the replacement  **
  97. **                      shall happen                               **
  98. **     toReplace      : (string) text which shall be replaced      **
  99. **     replace        : (string) text which shall be put in        **
  100. *********************************************************************
  101. ** ParseExpr : Parses a mathematical expression                    **
  102. **                                                                 **
  103. **   Syntax : result = ParseExpr(expression)                       **
  104. **                                                                 **
  105. **     result         : (single) result of the expression          **
  106. **     expression     : (string) expression to be parsed           **
  107. **                                                                 **
  108. ** Comment: Does only support +, -, /, *, \, (, and ). Parentheses **
  109. **          must not be nested. = statements are implemented and   **
  110. **          if both sides of the = are mathematical the same a 1   **
  111. **          will be returned, otherwise a 0.                       **
  112. *********************************************************************
  113.  
  114.  
  115.  
  116. *********************************************************************
  117. ** Special thanks go to  Herbert Breuer  who not just supported me **
  118. ** with great moral support during my work on  NAP   but also with **
  119. ** tips, hints and ideas, especially for the assembler routines.   **
  120. ********************************************************************}
  121.  
  122. ' structure definition, must be the same as in NAP.b
  123.  
  124. STRUCT Node
  125.  address   ln_Succ
  126.  address   ln_Pred
  127.  BYTE      ln_Type
  128.  BYTE      ln_Pri
  129.  ADDRESS   ln_Name
  130. END STRUCT
  131.  
  132. STRUCT _List
  133.  address   lh_Head
  134.  address   lh_Tail
  135.  address   lh_TailPred
  136.  BYTE      lh_Type
  137.  BYTE      l_pad
  138. END STRUCT
  139.  
  140. STRUCT StructNode
  141.  address   ln_Succ
  142.  address   ln_Pred
  143.  BYTE      ln_Type
  144.  BYTE      ln_Pri
  145.  ADDRESS   ln_Name
  146.  ADDRESS   member_types_list
  147. END STRUCT
  148.  
  149. STRUCT DefineNode
  150.  address   ln_Succ
  151.  address   ln_Pred
  152.  BYTE      ln_Type
  153.  BYTE      ln_Pri
  154.  ADDRESS   ln_Name
  155.  STRING    replace SIZE 200
  156.  SHORTINT  countparam
  157. END STRUCT
  158.  
  159.  
  160. sub address copy (string text) external
  161.  string dummy address alloc(len(text)+1,7)
  162.  
  163.  ' Let ACE do the hard work ;)
  164.  dummy=text
  165.  copy=@dummy
  166. end sub
  167.  
  168. sub shortint Search2 (shortint start,string text,string snippet) external
  169.  external longint _address1
  170.  external longint _address2
  171.  external longint _result
  172.  
  173.  _result=start
  174.  _address1=@text
  175.  _address2=@snippet
  176.  
  177.  ASSEM
  178.  
  179.       movem.l  a1-a3/d0-d2/d5,-(a7)         'save registers
  180.  
  181.       move.l   _address1,a1                 'set values
  182.       move.l   _address2,a2
  183.       move.l   _result,d2
  184.       subq.l   #1,d2
  185.       adda.l   d2,a1
  186.       move.b   (a2)+,d0                     'first byte of string2 to d0
  187.       move.l   a2,a3                        'begin of string2 (store)
  188.  
  189.       sub.l    d5,d5                        'clear d5
  190.  
  191.   search_loop1:
  192.  
  193.       cmp.b    #0,(a1)                      'end of string1?
  194.       beq.s    search_exit                  'if yes, exit
  195.  
  196.       cmp.b    (a1)+,d0                     'equal to begin of string2?
  197.       bne.s    search_loop1                 'if not, repeat loop
  198.  
  199.       move.l   a3,a2                        'begin of string2+1 to a2
  200.       move.l   a1,d1                        'backup of a1 to d1
  201.  
  202.   search_loop2:
  203.  
  204.       cmp.b    #0,(a2)                      'end of string2?
  205.       beq.s    search_found                 'if yes, exit (found :)
  206.  
  207.       cmpm.b   (a1)+,(a2)+                  'compare next byte
  208.       beq.s    search_loop2                 'if equal repeat loop
  209.  
  210.       move.l   d1,a1                        'restore pointer
  211.       bra.s    search_loop1                 'repeat outer loop
  212.  
  213.   search_found:
  214.  
  215.       move.l   d1,d5                        'begin of string2 in d1 to d5
  216.       move.l   _address1,d1                 'calculate difference between
  217.       sub.l    d1,d5                        ' found pos and begin of string1
  218.  
  219.   search_exit:
  220.  
  221.       move.l   d5,_result                   'move result to _result
  222.       movem.l  (a7)+,a1-a3/d0-d2/d5         'restore registers
  223.  
  224.  END ASSEM
  225.  
  226.  Search2=_result
  227. End SUB
  228.  
  229. sub shortint legal (string text,shortint position) external
  230.  EXTERNAL longint _result
  231.  EXTERNAL longint _address1
  232.  
  233.  _address1=@text
  234.  _result=position
  235.  
  236.  ASSEM
  237.  
  238.        movem.l a0/d0-d3/d5-d7,-(a7)      ' The comments for this routine
  239.                                          ' will be written when it should
  240.        move.l  _address1,a0              ' happen to me to get some time
  241.        move.l  _result,d0                ' left (perhaps next year)
  242.        add.l   d0,a0                     ' I assume this routine to be
  243.        move.b  #0,-(a0)                  ' very optimizable ...
  244.        move.l  _address1,a0
  245.  
  246.        moveq   #0,d1
  247.        moveq   #0,d5
  248.        moveq   #0,d6
  249.        moveq   #0,d7
  250.  
  251.        cmp.b   #1,d0
  252.        ble     _leg_set
  253.        subq    #1,d0
  254.  
  255.   _leg_loop:
  256.  
  257.        cmp.l   d1,d0
  258.        beq.s   _leg_exit
  259.  
  260.        move.b  (a0)+,d2
  261.        addq    #1,d1
  262.  
  263.        cmp.b   #123,d2
  264.        beq.s   _leg_c1
  265.        cmp.b   #34,d2
  266.        beq.s   _leg_c3
  267.        cmp.b   #39,d2
  268.        beq.s   _leg_c4
  269.        cmp.b   #82,d2
  270.        beq.s   _leg_REM
  271.        bra.s   _leg_loop
  272.  
  273.   _leg_c1:
  274.  
  275.        moveq   #1,d5
  276.  
  277.   _leg_c1_loop:
  278.  
  279.        cmp.b   #0,(a0)
  280.        beq.s   _leg_exit
  281.        addq    #1,d1
  282.        cmp.b   #125,(a0)+
  283.        bne.s   _leg_c1_loop
  284.        moveq   #0,d5
  285.        bra.s   _leg_loop
  286.  
  287.   _leg_c3:
  288.  
  289.        moveq   #1,d6
  290.  
  291.   _leg_c3_loop:
  292.  
  293.        cmp.b   #0,(a0)
  294.        beq.s   _leg_exit
  295.        addq    #1,d1
  296.        cmp.b   #34,(a0)+
  297.        bne.s   _leg_c3_loop
  298.        moveq   #0,d6
  299.        bra.s   _leg_loop
  300.  
  301.   _leg_c4:
  302.  
  303.        cmp.b   #0,d6
  304.        bne.s   _leg_loop
  305.  
  306.        addq    #1,d7
  307.        bra.s   _leg_exit
  308.  
  309.   _leg_REM:
  310.  
  311.        cmp.b   #0,d6
  312.        bne.s   _leg_loop
  313.  
  314.        addq    #1,d1
  315.        cmp.b   #69,(a0)+
  316.        bne.s   _leg_loop
  317.        cmp.b   #77,(a0)+
  318.        bne.s   _leg_loop
  319.        cmp.b   #32,(a0)+
  320.        bne.s   _leg_loop
  321.  
  322.        addq    #1,d7
  323.  
  324.   _leg_exit:
  325.  
  326.        move.l  #0,_result
  327.  
  328.        add.l   d5,d7
  329.        add.l   d6,d7
  330.        cmp.b   #0,d7
  331.        beq.s   _leg_set
  332.        bra.s   _leg_end
  333.  
  334.   _leg_set:
  335.  
  336.        move.l  #1,_result
  337.  
  338.   _leg_end:
  339.  
  340.        movem.l (a7)+,a0/d0-d3/d5-d7
  341.  
  342.  END ASSEM
  343.  
  344.  Legal=_result
  345. end sub
  346.  
  347. sub uppercase$(string lowercase) external
  348.  external longint _address3
  349.  _address3=@lowercase
  350.  
  351.  ASSEM
  352.  
  353.               movem.l   a0,-(a7)
  354.               move.l    _address3,a0
  355.  
  356.     uc_loop:
  357.  
  358.               cmp.b     #97,(a0)
  359.               blt.s     uc_loop_next
  360.  
  361.               cmp.b     #122,(a0)
  362.               bgt.s     uc_loop_next
  363.  
  364.               bclr.b    #5,(a0)
  365.  
  366.     uc_loop_next:
  367.  
  368.               tst.b    (a0)+
  369.               bne.s    uc_loop
  370.  
  371.               movem.l  (a7)+,a0
  372.  
  373.  END ASSEM
  374.  
  375.  uppercase$=lowercase
  376. END SUB
  377.  
  378. sub string CutOff (string text,shortint FoundSth) external
  379.  if legal(text,FoundSth) then CutOff=left$(text,FoundSth-1) else CutOff=text
  380. end sub
  381.  
  382. SUB STRING Get_name_of_object (SHORTINT startpos, STRING text) external
  383.  EXTERNAL LONGINT _start
  384.  EXTERNAL LONGINT _end
  385.  EXTERNAL LONGINT _pointer
  386.  
  387.  _start=startpos-1
  388.  _end=0
  389.  _pointer=@text
  390.  
  391.  ASSEM
  392.  
  393.      movem.l  d0-d5/a0,-(a7)           { save registers              }
  394.      move.l   _pointer,a0
  395.      add.l    _start,a0
  396.      moveq.l  #0,d0
  397.  
  398.   _gno_loop1:
  399.  
  400.      move.b   (a0),d0
  401.      sub.b    #32,d0                   { <> SPACE -> exit            }
  402.      bne.s    _gno_ex_l1
  403.      add.l    #1,a0
  404.      bra.s    _gno_loop1
  405.  
  406.   _gno_ex_l1:
  407.  
  408.      move.l   a0,_pointer
  409.  
  410.   _gno_loop2:
  411.  
  412.      move.b   (a0)+,d0
  413.      sub.b    #0,d0
  414.      beq.s    _gno_exit                { = EOS -> exit               }
  415.  
  416.      sub.b    #32,d0
  417.      beq.s    _gno_exit                { = SPACE -> exit             }
  418.  
  419.      bra.s    _gno_loop2               { else repeat                 }
  420.  
  421.   _gno_exit:
  422.  
  423.      move.l   a0,_end
  424.      movem.l  (a7)+,d0-d5/a0           { restore registers           }
  425.  
  426.  END ASSEM
  427.  
  428.  Get_name_of_object=left$(CSTR(_pointer),_end-_pointer-1)
  429. END SUB
  430.  
  431. SUB STRING Get_name_of_object_alt (SHORTINT startpos, STRING text) external
  432.  EXTERNAL LONGINT _start
  433.  EXTERNAL LONGINT _end
  434.  EXTERNAL LONGINT _pointer
  435.  
  436.  _start=startpos
  437.  _end=0
  438.  _pointer=@text
  439.  
  440.  ASSEM
  441.  
  442.      movem.l  d0-d5/a0,-(a7)           ' save registers
  443.      move.l   _pointer,a0              ' set values
  444.      add.l    _start,a0                ' add start difference
  445.      moveq.l  #0,d0
  446.      subq.l   #1,a0
  447.  
  448.   _gnoa_loop1:
  449.  
  450.      move.b   (a0)+,d0
  451.  
  452.      cmp.b    #0,d0
  453.      beq.s    _gnoa_ex_l1
  454.  
  455.      cmp.b    #46,d0                   ' = "." then exit
  456.      beq.s    _gnoa_ex_l1
  457.  
  458.      cmp.b    #48,d0                   ' < "0" then repeat
  459.      blt.s    _gnoa_loop1
  460.      cmp.b    #57,d0                   ' <= "9" then exit
  461.      ble.s    _gnoa_ex_l1
  462.  
  463.      cmp.b    #65,d0                   ' < "A" then repeat
  464.      blt.s    _gnoa_loop1
  465.      cmp.b    #90,d0                   ' <= "Z" then exit
  466.      ble.s    _gnoa_ex_l1
  467.  
  468.      cmp.b    #95,d0                   ' = "_" then exit
  469.      beq.s    _gnoa_ex_l1
  470.  
  471.      cmp.b    #97,d0                   ' < "a" then repeat
  472.      blt.s    _gnoa_loop1
  473.      cmp.b    #122,d0                  ' > "z" then repeat
  474.      bgt.s    _gnoa_loop1
  475.  
  476.   _gnoa_ex_l1:
  477.  
  478.      subq.l   #1,a0
  479.      move.l   a0,_pointer
  480.  
  481.   _gnoa_loop2:
  482.  
  483.      move.b   (a0)+,d0
  484.      cmp.b    #0,d0
  485.      beq.s    _gnoa_exit                { = EOS -> exit               }
  486.  
  487.      cmp.b    #46,d0                   ' = "." then repeat
  488.      beq.s    _gnoa_loop2
  489.  
  490.      cmp.b    #48,d0                   ' < "0" then exit
  491.      blt.s    _gnoa_exit
  492.      cmp.b    #57,d0                   ' <= "9" then repeat
  493.      ble.s    _gnoa_loop2
  494.  
  495.      cmp.b    #65,d0                   ' < "A" then exit
  496.      blt.s    _gnoa_exit
  497.      cmp.b    #90,d0                   ' <= "Z" then repeat
  498.      ble.s    _gnoa_loop2
  499.  
  500.      cmp.b    #95,d0                   ' = "_" then repeat
  501.      beq.s    _gnoa_loop2
  502.  
  503.      cmp.b    #97,d0                   ' < "a" then exit
  504.      blt.s    _gnoa_exit
  505.      cmp.b    #122,d0                  ' <= "z" then repeat
  506.      ble.s    _gnoa_loop2
  507.  
  508.   _gnoa_exit:
  509.  
  510.      move.l   a0,_end
  511.      movem.l  (a7)+,d0-d5/a0           { restore registers           }
  512.  
  513.  END ASSEM
  514.  
  515.  Get_name_of_object_alt=left$(CSTR(_pointer),_end-_pointer-1)
  516. END SUB
  517.  
  518. {* This routine is obsolete since NAP V2.00b2. I have included it  **
  519. ** because there might be use. In further versions this routine    **
  520. ** won't be implemented any more ! Contact me if you wanna know    **
  521. ** how to use it (special structures!)                             *}
  522. sub address AlreadyInList (address begin_of_list,string what) external
  523.  external longint _result
  524.  external longint _address1
  525.  external longint _address2
  526.  
  527.  _address1=begin_of_list
  528.  _address2=@what
  529.  
  530.  ASSEM
  531.  
  532.      movem.l  a0-a1,-(sp)
  533.      move.l   _address1,a0
  534.      move.l   _address2,a1
  535.      move.l   #0,_result
  536.  
  537.   AL_loop:
  538.  
  539.      cmp.l    #0,100(a0)               ' 100 = Offset for nextone
  540.      beq.s    AL_exit
  541.  
  542.      movea.l  a1,a2
  543.      movea.l  a0,a3
  544.  
  545.   AL_comploop:
  546.  
  547.      cmpm.b   (a2)+,(a3)+
  548.      beq.s    AL_comploop_2
  549.  
  550.      move.l   100(a0),a0
  551.      bra.s    AL_loop
  552.  
  553.   AL_comploop_2:
  554.  
  555.      cmp.b    #0,-(a2)
  556.      beq.s    AL_comploop_exit
  557.      addq     #1,a2
  558.      bra.s    AL_comploop
  559.  
  560.   AL_comploop_exit:
  561.  
  562.      move.l   a0,_result
  563.  
  564.   AL_exit:
  565.  
  566.      movem.l  (sp)+,a0-a1
  567.  
  568.  END ASSEM
  569.  
  570.  AlreadyInList=_result
  571. END SUB
  572.  
  573. SUB STRING ReplaceC (string text,string toReplace,string replace) external
  574.  shortint foundsth
  575.  
  576.  foundSth=search2(1,text,toReplace)
  577.  WHILE foundSth
  578.   IF legal(text,foundsth) THEN text=LEFT$(text,foundsth-1)+~
  579.                                     replace+MID$(text,foundsth+2)
  580.   foundSth=search2(foundsth+1,text,toReplace)
  581.  WEND
  582.  ReplaceC=text
  583. END SUB
  584.  
  585. {* Could be optimized in later versions and even expanded!         *}
  586. SUB SINGLE ParseExpr(STRING expression_org) EXTERNAL
  587.  SHORTINT i,j,foundend,start,ende,escape,doubleExpr
  588.  SINGLE   erg,erg2
  589.  STRING   char SIZE 2
  590.  STRING   lexpr,rexpr,operators SIZE 20
  591.  STRING   expression ADDRESS ALLOC(1025,7)
  592.  
  593.  expression=expression_org
  594.  
  595.  
  596.  start=INSTR(1,expression,"=")
  597.  IF start THEN
  598.   ++doubleExpr
  599.   erg2=ParseExpr(MID$(expression,start+1))
  600.   expression=LEFT$(expression,start-1)
  601.  END IF
  602.  
  603.  REPEAT
  604.   start=INSTR(1,expression,"(")
  605.   IF start THEN
  606.    ende=INSTR(1,expression,")")
  607.    expression=LEFT$(expression,start-1)+~
  608.               STR$(ParseExpr(MID$(expression,start+1,ende-start-1)))+~
  609.               MID$(expression,ende+1)
  610.    EXIT FOR
  611.   ELSE
  612.    ++escape
  613.   END IF
  614.  UNTIL escape
  615.  
  616.  operators="+-/*\"
  617.  
  618.  --escape
  619.  REPEAT
  620.   FOR i=1 TO LEN(expression)
  621.    char=MID$(expression,i,1)
  622.    IF char="*" OR char="\" OR char="/" THEN
  623.     start=1
  624.     FOR j=i-1 TO 1 STEP -1
  625.      IF INSTR(1,operators,MID$(expression,j,1)) THEN
  626.       IF j>1 THEN
  627.        IF INSTR(1,operators,MID$(expression,j-1,1))=0 THEN
  628.         start=j+1
  629.         EXIT FOR
  630.        END IF
  631.       END IF
  632.      END IF
  633.     NEXT
  634.     lexpr=MID$(expression,start,i-start)
  635.     IF lexpr="" THEN ++escape
  636.  
  637.     ende=LEN(Expression)
  638.     FOR j=i+1 TO len(expression)
  639.      IF INSTR(1,operators,MID$(expression,j,1)) THEN
  640.       IF j>i+1 THEN ende=j-1:EXIT FOR
  641.      END IF
  642.     NEXT
  643.     rexpr=MID$(expression,i+1,ende-i)
  644.  
  645.     CASE
  646.      char="*":erg=VAL(lexpr)*VAL(rexpr)
  647.      char="\":erg=VAL(lexpr)\VAL(rexpr)
  648.      char="/":erg=VAL(lexpr)/VAL(rexpr)
  649.     END CASE
  650.  
  651.     expression=LEFT$(expression,start-1)+STR$(erg)+MID$(expression,ende+1)
  652.     EXIT FOR
  653.    ELSE
  654.     IF i=LEN(expression) THEN ++escape
  655.    END IF
  656.   NEXT
  657.  UNTIL escape
  658.  
  659.  --escape
  660.  REPEAT
  661.   FOR i=2 TO LEN(expression)
  662.    char=MID$(expression,i,1)
  663.    IF char="+" OR char="-" THEN
  664.     lexpr=LEFT$(expression,i-1)
  665.     expression=MID$(expression,i+1)
  666.  
  667.     FOR j=1 TO LEN(expression)
  668.      IF INSTR(1,operators,MID$(expression,j,1)) THEN
  669.       IF j>1 THEN
  670.        rexpr=LEFT$(expression,j-1)
  671.        expression=MID$(expression,j)
  672.        EXIT FOR
  673.       END IF
  674.      ELSE
  675.       rexpr=LEFT$(expression,j)
  676.       IF j=LEN(expression) THEN expression=""
  677.      END IF
  678.     NEXT
  679.  
  680.     CASE
  681.      char="-":erg=VAL(lexpr)-VAL(rexpr)
  682.      char="+":erg=VAL(lexpr)+VAL(rexpr)
  683.     END CASE
  684.  
  685.     expression=STR$(erg)+expression
  686.     EXIT FOR
  687.    ELSE
  688.     IF i=LEN(expression) THEN ++escape
  689.    END IF
  690.   NEXT
  691.  UNTIL escape
  692.  
  693.  IF DoubleExpr THEN
  694.   IF VAL(expression)=erg2 THEN
  695.    expression="1"
  696.   ELSE
  697.    expression="0"
  698.   END IF
  699.  END IF
  700.  
  701.  ParseExpr=val(expression)
  702. end sub
  703.  
  704. ASSEM
  705.  _address1: dc.l 0
  706.  _address2: dc.l 0
  707.  _address3: dc.l 0
  708.  _result:   dc.l 0
  709.  _start:    dc.l 0
  710.  _pointer:  dc.l 0
  711.  _end:      dc.l 0
  712. END ASSEM
  713.